package fishBids.group3.behaviour.bank;

import es.upm.agents.ontology.ToSellProduct;
import es.upm.agents.ontology.ToSellProductResponse;
import fishBids.group3.AgBank;
import fishBids.group3.behaviour.bank.model.Account;
import fishBids.group3.common.Constants;
import fishBids.group3.utils.Utils;
import jade.content.Concept;
import jade.content.ContentElement;
import jade.content.lang.Codec;
import jade.content.lang.Codec.CodecException;
import jade.content.onto.Ontology;
import jade.content.onto.OntologyException;
import jade.content.onto.UngroundedException;
import jade.content.onto.basic.Action;
import jade.core.AID;
import jade.core.behaviours.CyclicBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;

public class BankSellProductBehaviour extends CyclicBehaviour {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4218560108006303061L;
	
	public BankSellProductBehaviour(Codec codec, Ontology ontology, AgBank bankAg){
		this.codec = codec;
		this.ontology = ontology;
		this.bankAg = bankAg;
	}

	@Override
	public void action() {

		// Waits for sellProduct requests
		// Receive the message 
		//System.out.println("Bank>>> waiting for a sell product request");
		ACLMessage msg = bankAg.receive(MessageTemplate.and(
				MessageTemplate.MatchPerformative(ACLMessage.REQUEST),
				MessageTemplate.MatchProtocol(Constants.SELL_PRODUCT) )); 

		if (msg != null)

		{
				  AID sellingBidder = msg.getSender();
				  String agentName = msg.getSender().getName();
				  ContentElement ce;
				try {
					ce = bankAg.getContentManager().extractContent(msg);
				  if( ce instanceof Action ){
					  Action ac = (Action)ce;
					  Concept cpt = ac.getAction();
					  if( cpt instanceof ToSellProduct ){
						  ToSellProduct toSellProduct = (ToSellProduct) cpt;
//						  System.out.println("BANK>> receive SellProduct of type: " + toSellProduct.getProductType().getType() 
//								  + " with amount:" + toSellProduct.getAmount());

						//Sending agree message of the protocol
						ACLMessage reply = msg.createReply();
						reply.setLanguage(codec.getName());
						reply.setOntology(ontology.getName());
						reply.setPerformative(ACLMessage.AGREE);
						//System.out.println("BANK >> send AGREE protocol sell Product");
						bankAg.send(reply);
						
						//Check if the agent can sell this amount
						Account account = (Account) this.bankAg.getAgentsAccounts().get(agentName);
						Float amount = (Float) account.getItems().get(toSellProduct.getProductType().getType() );
						if(toSellProduct.getAmount() > amount ){
							Utils.sendMessage(ACLMessage.FAILURE, codec, ontology, sellingBidder, 
									Constants.SELL_PRODUCT, this.bankAg);
							return;
						}
						
						//selling the product to the market
						Utils.sendMessageWithConcept(ACLMessage.REQUEST, codec, ontology, this.bankAg.getMarketID(),
								Constants.SELL_PRODUCT, this.bankAg, toSellProduct);
						
						msg = bankAg.blockingReceive(MessageTemplate.and(
								MessageTemplate.MatchPerformative(ACLMessage.INFORM),
								MessageTemplate.MatchProtocol(Constants.SELL_PRODUCT) )); 
						
						ToSellProductResponse toSellProductResponse = (ToSellProductResponse) Utils.extractContent(this.bankAg, msg);
						
						account.setBalance(account.getBalance() + toSellProductResponse.getRevenue() );
						
						if(amount == null){
							amount = new Float(0);
						}
						float newAmount = amount.floatValue() - toSellProduct.getAmount();
						
//						System.out.println("Bank >>>> new amount of product of type " + toSellProduct.getProductType().getType() + ": " + 
//								newAmount);
						
						account.getItems().put(toSellProduct.getProductType().getType(), new Float(newAmount) );
						//System.out.println("BANK >>Sending INFORM protocol sellProduct ");
						Utils.sendMessageWithConcept(ACLMessage.INFORM, codec, ontology,sellingBidder , Constants.BUY_PRODUCT, this.bankAg, toSellProductResponse);
						
					  }
				  }
				} catch (UngroundedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (CodecException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (OntologyException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}



		}else{
			//A message was not received
			this.block();
		}



	}
	
	Codec codec;
	Ontology ontology;
	AgBank bankAg;

}
